//
//  UIButton+LBExpandHitTest.m
//  LBButtonExpandHitTest
//
//  Created by Apple on 2021/9/19.
//

#import "UIButton+LBExpandHitTest.h"
#import <objc/runtime.h>


@implementation UIButton (LBExpandHitTest)
@dynamic expandHitEdgeInsets;
@dynamic expandTopHitEdge;
@dynamic expandLeftHitEdge;
@dynamic expandBottomHitEdge;
@dynamic expandRightHitEdge;
@dynamic isAutoHitExpand;

static const NSString *KEY_EXPAND_HIT_EDGE_INSETS = @"expandHitEdgeInsets";
static const NSString *KEY_EXPAND_TOP_EDGE = @"expandTopHitEdge";
static const NSString *KEY_EXPAND_LEFT_EDGE = @"expandLeftHitEdge";
static const NSString *KEY_EXPAND_BOTTOM_EDGE = @"expandBottomHitEdge";
static const NSString *KEY_EXPAND_RIGHT_EDGE = @"expandRightHitEdge";
static const NSString *KEY_IS_AUTO_HIT_EXPAND = @"isAutoHitExpand";

- (void)setIsAutoHitExpand:(BOOL)isAutoHitExpand {
     NSValue *value = [NSValue value:&isAutoHitExpand withObjCType:@encode(BOOL)];
     objc_setAssociatedObject(self, &KEY_IS_AUTO_HIT_EXPAND, value, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (BOOL)isAutoHitExpand {
    NSValue *value = objc_getAssociatedObject(self, &KEY_IS_AUTO_HIT_EXPAND);
    if(value) {
        BOOL isAllowedHitExpand;
        [value getValue:&isAllowedHitExpand];
        return isAllowedHitExpand;
    }else {
        return NO;
    }
}

-(void)setExpandHitEdgeInsets:(UIEdgeInsets)expandHitEdgeInsets {
    NSValue *value = [NSValue value:&expandHitEdgeInsets withObjCType:@encode(UIEdgeInsets)];
    objc_setAssociatedObject(self, &KEY_EXPAND_HIT_EDGE_INSETS, value, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

-(UIEdgeInsets)expandHitEdgeInsets {
    NSValue *value = objc_getAssociatedObject(self, &KEY_EXPAND_HIT_EDGE_INSETS);
    if(value) {
        UIEdgeInsets edgeInsets; [value getValue:&edgeInsets];
        return edgeInsets;
    }else {
        return UIEdgeInsetsZero;
    }
}

- (void)setExpandTopHitEdge:(CGFloat)expandTopHitEdge {
    NSValue *value = [NSValue value:&expandTopHitEdge withObjCType:@encode(CGFloat)];
    objc_setAssociatedObject(self, &KEY_EXPAND_TOP_EDGE, value, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (CGFloat)expandTopHitEdge {
    NSValue *value = objc_getAssociatedObject(self, &KEY_EXPAND_TOP_EDGE);
    if (value) {
        CGFloat topEdge  ;
        [value getValue:&topEdge];
        return topEdge;
    }
    else {
        return 0;
    }
}

- (void)setExpandLeftHitEdge:(CGFloat)expandLeftHitEdge {
    NSValue *value = [NSValue value:&expandLeftHitEdge  withObjCType:@encode(CGFloat)];
    objc_setAssociatedObject(self, &KEY_EXPAND_LEFT_EDGE, value, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (CGFloat)expandLeftHitEdge {
    NSValue *value = objc_getAssociatedObject(self, &KEY_EXPAND_LEFT_EDGE);
    if (value) {
        CGFloat leftEdge  ;
        [value getValue:&leftEdge];
        return leftEdge;
    }
    else {
        return 0;
    }
}

- (void)setExpandBottomHitEdge:(CGFloat)expandBottomHitEdge {
    NSValue *value = [NSValue value:&expandBottomHitEdge  withObjCType:@encode(CGFloat)];
    objc_setAssociatedObject(self, &KEY_EXPAND_BOTTOM_EDGE, value, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (CGFloat)expandBottomHitEdge {
    NSValue *value = objc_getAssociatedObject(self, &KEY_EXPAND_BOTTOM_EDGE);
    if (value) {
        CGFloat bottomEdge  ;
        [value getValue:&bottomEdge];
        return bottomEdge;
    }
    else {
        return 0;
    }
}

- (void)setExpandRightHitEdge:(CGFloat)expandRightHitEdge {
    NSValue *value = [NSValue value:&expandRightHitEdge  withObjCType:@encode(CGFloat)];
    objc_setAssociatedObject(self, &KEY_EXPAND_RIGHT_EDGE, value, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (CGFloat)expandRightHitEdge {
    NSValue *value = objc_getAssociatedObject(self, &KEY_EXPAND_RIGHT_EDGE);
    if (value) {
        CGFloat rightEdge  ;
        [value getValue:&rightEdge];
        return rightEdge;
    }
    else {
        return 0;
    }
}

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
    CGFloat top = 0;
    CGFloat left = 0;
    CGFloat bottom = 0;
    CGFloat right = 0;
    //设置默认的扩展量优先级最低
    if (self.isAutoHitExpand) {
        if (self.frame.size.height < 44) {
            top = (44 - self.frame.size.height)/2.0;
            bottom = (44 - self.frame.size.height)/2.0;
        }
        if (self.frame.size.width < 44) {
            left = (44 - self.frame.size.width)/2.0;
            right = (44 - self.frame.size.width)/2.0;
        }
    }
    //设置四个偏移量次之
    if (!UIEdgeInsetsEqualToEdgeInsets(self.expandHitEdgeInsets, UIEdgeInsetsZero)) {
        top = self.expandHitEdgeInsets.top;
        left = self.expandHitEdgeInsets.left;
        bottom = self.expandHitEdgeInsets.bottom;
        right = self.expandHitEdgeInsets.right;
    }
    //单独设置的偏移量优先级最高
    if (self.expandTopHitEdge) {
        top = self.expandTopHitEdge;
    }
    if (self.expandLeftHitEdge) {
        left = self.expandLeftHitEdge;
    }
    if (self.expandBottomHitEdge) {
        bottom = self.expandBottomHitEdge;
    }
    if (self.expandRightHitEdge) {
        right = self.expandRightHitEdge;
    }
    //添加负号使相应的内边距变为向外扩展
    UIEdgeInsets hitExpandEdge = UIEdgeInsetsMake(- top, - left, - bottom, -right);
    if(UIEdgeInsetsEqualToEdgeInsets(hitExpandEdge, UIEdgeInsetsZero) ||       !self.enabled || self.hidden) {
        return [super pointInside:point withEvent:event];
    }
    CGRect relativeFrame = self.bounds;
    CGRect hitFrame = UIEdgeInsetsInsetRect(relativeFrame, hitExpandEdge);
    return CGRectContainsPoint(hitFrame, point);
}

@end
